package xyz.eden.cloud.common.web.support.infrastructure.resource;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.eden.cloud.common.core.exception.BusinessException;
import xyz.eden.cloud.common.core.exception.ParameterException;
import xyz.eden.cloud.common.core.result.ResultSetEnum;
import xyz.eden.cloud.common.core.util.AssertUtils;
import xyz.eden.cloud.common.web.support.infrastructure.db.po.BasePO;

/**
 * IBaseOperateResource
 */
public interface BaseOperateResource<PO extends BasePO> extends IService<PO> {

    /**
     * 添加信息
     *
     * @param po
     * @return
     */
    default Long addInfo(PO po) throws Exception {
        // 1. 参数校验
        Boolean verifyResult = this.verifyAddInfo(po);
        AssertUtils.isTrue(verifyResult, new ParameterException("verify add info fail."));
        // 2. 模型转换
        PO addInfo = this.builderAddInfo(po);
        AssertUtils.notNull(addInfo, new ParameterException("builder add info is null."));
        // 3. 添加信息
        BaseMapper<PO> baseMapper = this.getBaseMapper();
        int insertResult = baseMapper.insert(addInfo);
        if (insertResult != 1) {
            throw new BusinessException(ResultSetEnum.ERROR_BUSINESS.getCode(), "add info fail.");
        }
        return addInfo.getId();
    }

    /**
     * 构建添加信息
     *
     * @param po
     * @return
     */
    PO builderAddInfo(PO po);

    /**
     * 验证添加信息
     *
     * @param po
     * @return
     */
    Boolean verifyAddInfo(PO po);

    /**
     * 通过 id 更新信息
     *
     * @param po
     * @return
     */
    default Boolean updateInfoById(PO po) throws Exception {
        // 1. 参数校验
        Boolean verifyResult = this.verifyUpdateInfo(po);
        AssertUtils.isTrue(verifyResult, new ParameterException("verify update info fail."));
        // 2. 模型转换
        PO updateInfo = this.builderUpdateInfo(po);
        AssertUtils.notNull(updateInfo, new ParameterException("builder update info is null."));
        AssertUtils.notNull(updateInfo.getId(), new ParameterException("builder update info id is null."));
        // 3. 添加信息
        BaseMapper<PO> baseMapper = this.getBaseMapper();
        int insertResult = baseMapper.updateById(updateInfo);
        if (insertResult != 1) {
            throw new BusinessException(ResultSetEnum.ERROR_BUSINESS.getCode(), "add info fail.");
        }
        return true;
    }

    /**
     * 构建更新信息
     *
     * @param po
     * @return
     */
    PO builderUpdateInfo(PO po);

    /**
     * 验证更新信息
     *
     * @param po
     * @return
     */
    Boolean verifyUpdateInfo(PO po);
}
